core.HTMLPanel = function(config){
    this.init(config);
}

core.extendClass('core.HTMLPanel', 'core.form.UIControl');

core.HTMLPanel.prototype.init = function(config){
    var instance = this;
    this.xType = 'html';
    this.superCall('init', arguments, config);
    this.content = core.newDiv(this.div, 'scroll_wrapper');
    this.table = core.newElement(this.content, 'table', 'html_panel_table');
    this.tr = core.newElement(this.table, 'tr');
    this.td = core.newElement(this.tr, 'td');
    this.contentDiv = core.newDiv(this.td, 'html_panel_content');
    if(config.cls){
        $(this.contentDiv).addClass(config.cls);
    }
    if(config.bottom){
        this.bottom = true;
        $(this.td).css('vertical-align', 'bottom');
        this.td.valign = 'bottom';
    }else{
        $(this.td).css('vertical-align', 'top');
        this.td.valign = 'top';
    }
//#ifdef DESKTOP
    $(this.content).addClass('scrollable');
//#endif
    $(this.td).click(function(){
        instance.focus();
        return true;
    });
    $(this.contentDiv).html(config.html || '&nbsp;');
};

core.HTMLPanel.prototype.bodyChanged = function(){
    this.fire('body_change');
};

core.HTMLPanel.prototype.setHTML = function(aHTML){
    $(this.contentDiv).html(aHTML || '&nbsp;');
    this.bodyChanged();
}

core.HTMLPanel.prototype.addContent = function(aContent){
    $(this.contentDiv).append(aContent);
}

core.HTMLPanel.prototype.makeResize = function(aX, aY, aWidth, aHeight){
    $(this.content).width(aWidth).height(aHeight);
//#ifdef DESKTOP
    if(this.bottom){
        var h = $(this.table).height();
        core.setTimeout(this.content, function(h){
            $(this).scrollTop(h);
        }, 1, h);
    }
//#endif
};

//#ifdef MOBILE
core.HTMLPanel.prototype.setWidth = function(aWidth){
	this.width = aWidth;
	$(this.div).width(aWidth);
    this.minHeight = $(this.contentDiv).outerHeight();
//    core.log('HTMLPanel: minHeight: '+this.minHeight);
};
//#endif

core.grid = {};

core.grid.COLUMN_INTERVAL = 1;
core.grid.ROW_INTERVAL = 1;

core.grid.SCROLLBAR_OFFSET = 17;
//#ifdef MOBILE
core.grid.SCROLLBAR_OFFSET = 0;
//#endif

core.grid.GridPanel = function(config){
    this.init(config);
}

core.extendClass('core.grid.GridPanel', 'core.form.UIControl');

core.grid.GridPanel.prototype.updatePager = function(aData){
    if(this.pager && aData){
        this.pagerLbl.setText(aData.page+'/'+aData.pages);
        this.pages = aData.pages;
        this.page = aData.page;

        this.goFirst.setDisabled(this.page==1);
        this.goLeft.setDisabled(this.page==1);

        this.goRight.setDisabled(this.page==this.pages);
        this.goLast.setDisabled(this.page==this.pages);
//        this.pagerBox.refresh();
    }
};

core.grid.GridPanel.prototype.changePage = function(aDirection, aHandler){
    var instance = this;
    if(!this.fire('change_page', aDirection)){
        core.log('already handled');
        return;
    }
    if(this.frame){
        this.frame.send({
            method: 'loadGrid',
            message: {
                direction: aDirection
            },
            ok: function(aData){
                instance.loadGrid(aData);
                if(aHandler)
                    aHandler();
            },
            disableItem: instance
        });
    }else{
        core.log('!no frame');
    }
}

core.grid.GridPanel.prototype.init = function(config){
    this.xType = 'grid';
    this.superCall('init', arguments, config);
    this.frame = config.frame;

    this.allowRowSelect = config.allowRowSelect || false;
    this.idIndex = config.idIndex;

    this.headerCaptions = $.makeArray(config.headerCaptions);
    this.headerVisible = config.headerCaptions;
    this.columnDef = [];
    this.childComponents = [];
    var def = config.columns || '1';
    var arr = def.split(',');
    this.colCount = arr.length;
    this.fixedWidth = (this.colCount-1)*core.grid.COLUMN_INTERVAL;
    this.floatWidth = 0;
    for(var i = 0; i<arr.length; i++){
        var f = parseFloat(arr[i]);
        if(!f)
            f = 1;
        this.columnDef[i] = f;
        if(f<=1)
            this.floatWidth += f;
        else
            this.fixedWidth += f;
    }
    this.minWidth = this.fixedWidth;
    this.pager = config.pager || false;
    this.pagerBox = config.pagerBox;
    if(!this.pagerBox)
        this.pager = false;
    if(this.pager){
        var instance = this;
        this.goLeft = new core.form.Button({
            icon: 'tab_icon tab_left_btn',
            handler: function(){
                instance.changePage('left');
            }
        });
        this.goRight = new core.form.Button({
            icon: 'tab_icon tab_right_btn',
            handler: function(){
                instance.changePage('right');
            }
        });
        this.goFirst = new core.form.Button({
            icon: 'tab_icon tab_first_btn',
            align: 'right',
            handler: function(){
                instance.changePage('first');
            }
        });
        this.goLast = new core.form.Button({
            icon: 'tab_icon tab_last_btn',
            handler: function(){
                instance.changePage('last');
            }
        });
        this.pagerLbl = new core.Label({
            text: '1/1',
            minWidth: 40,
            align: 'center',
            valign: 'middle'
        });
        this.pagerBox.setContent([this.goFirst, this.goLeft, this.pagerLbl, this.goRight, this.goLast], 'd,d,d,d,d', 'd');
        this.pagerBox.updateLayout();
    }
    if(this.headerVisible){
        this.header = core.newElement(this.div, 'table', 'grid_header');
        $(this.header).attr('cellpadding', 0).attr('cellspacing', 0).css('border', 0);
        this.headerTR = core.newElement(this.header, 'tr', 'grid_header_tr');
        for (var i = 0; i < this.colCount; i++) {
            if(i>0){
                $(core.newElement(this.headerTR, 'td', 'grid_header_delim')).
                    text('').width(core.grid.COLUMN_INTERVAL);
            }
            $(core.newElement(this.headerTR, 'td', 'grid_header_td')).
                        html(this.headerCaptions[i]);
        }
    }
    this.gridDiv = core.newDiv(this.div, 'grid_div');
    this.grid = core.newElement(this.gridDiv, 'table', 'grid');
    $(this.grid).attr('cellpadding', 0).attr('cellspacing', 0).css('border', 0);
    this.rowCount = 0;
    this.data = [];
    this.rows = [];
    this.firstRow = core.newElement(this.grid, 'tr');
    $(this.firstRow).height(0);
    for (var i = 0; i < this.colCount; i++) {
        if(i>0){
            $(core.newElement(this.firstRow, 'td', 'grid_header_delim')).
                text('').width(core.grid.COLUMN_INTERVAL).height(0);
        }        
            $(core.newElement(this.firstRow, 'td', 'grid_header_delim')).
                html('').height(0);
    }
    $(this.grid).append(this.makeDelimRow());
    this.updatePager({
        page: 1,
        pages: 1
    });

    if(this.frame){
        this.frame.setMessageHandler('gridItemAdded', this, this.gridItemAdded);
        this.frame.setMessageHandler('gridItemRemoved', this, this.gridItemRemoved);
        this.frame.setMessageHandler('gridItemSelected', this, this.gridItemSelected);
        this.frame.setMessageHandler('loadGrid', this, this.loadGrid);
        this.frame.setMessageHandler('setGridState', this, this.setGridState);
    }
};

core.grid.GridPanel.prototype.bodyChanged = function(){
    this.fire('body_change');
};

core.grid.GridPanel.prototype.makeDelimRow = function(){
    var tr = document.createElement('tr');
    $(core.newElement(tr, 'td', 'grid_row_delim_td')).
            attr('colSpan', 2*this.colCount-1).html('&nbsp;').height(core.grid.ROW_INTERVAL);
    $(tr).addClass('grid_row_delim_tr');
    return tr;
};

core.grid.GridPanel.prototype.appendRow = function(aData){
    return this.addRow(this.rowCount, aData);
};

core.grid.GridPanel.prototype.clear = function(){
    this.childComponents = [];
    while(this.rowCount>0){
        this.removeRow(0);
    }
};

core.grid.GridPanel.prototype.getScrollInfo = function(aID){
    //First, find index
    var scroll = 0;
    var tbody = $(this.grid).children().get(0);
    for (var i = 0; i < this.data.length; i++) {
        if(this.data[i][this.idIndex]==aID){
//#ifdef DESKTOP
            var frameHeight = $(this.gridDiv).outerHeight();
            var rowHeight = $($(tbody).children().get(2*i+2)).outerHeight()+$($(tbody).children().get(2*i+1)).outerHeight();
            var currentScroll = $(this.gridDiv).scrollTop();
            return {
                scroll: currentScroll,
                rowHeight: rowHeight,
                frameHeight: frameHeight,
                rowTop: scroll
            }
//#endif
//#ifdef MOBILE
            return {
                scroll: currentScroll,
                rowHeight: rowHeight,
                frameHeight: 0,
                rowTop: scroll
            }
//            var pos = this.getPosition();
//            var y = pos.y;
//            if(this.headerVisible){
//                y += $(this.header).height();
//            }
//            window.scrollTo(0, y+scroll);
//#endif
        }else{
            scroll += ($($(tbody).children().get(2*i+2)).outerHeight()+$($(tbody).children().get(2*i+1)).outerHeight());
        }
    }
    return null;
}

core.grid.GridPanel.prototype.moveFrame = function(aID){
    //First, find index
    var scroll = 0;
    var tbody = $(this.grid).children().get(0);
    for (var i = 0; i < this.data.length; i++) {
        if(this.data[i][this.idIndex]==aID){
//#ifdef DESKTOP
            var frameHeight = $(this.gridDiv).outerHeight();
            var rowHeight = $($(tbody).children().get(2*i+2)).outerHeight()+$($(tbody).children().get(2*i+1)).outerHeight();
            var currentScroll = $(this.gridDiv).scrollTop();
            if(scroll<currentScroll){
                $(this.gridDiv).scrollTop(scroll);
            }else{
                if(scroll+rowHeight>currentScroll+frameHeight){
                    var newScroll = scroll+rowHeight-frameHeight;
                    if(scroll<newScroll)
                        newScroll = scroll;
                    $(this.gridDiv).scrollTop(newScroll);
                }
            }
//#endif
//#ifdef MOBILE
            var pos = this.getPosition();
            var y = pos.y;
            if(this.headerVisible){
                y += $(this.header).height();
            }
            window.scrollTo(0, y+scroll);
//#endif
            return true;
        }else{
            scroll += ($($(tbody).children().get(2*i+2)).outerHeight()+$($(tbody).children().get(2*i+1)).outerHeight());
        }
    }
    return false;
};

core.grid.GridPanel.prototype.removeRow = function(aIndex){
    if(aIndex>=this.rowCount){
        aIndex = this.rowCount-1;
    }
    if(this.selected && this.selected==this.data[aIndex][this.idIndex]){
        this.fire('unselect', {}, this.selected, this.selectedRow);
        this.selected = null;
        this.selectedRow = null;
    }
    var row = this.data[aIndex];
    for (var i = 0; i < row.length; i++) {
        if(row[i].instanceID){
            for (var j = 0; j < this.childComponents.length; j++) {
                if(this.childComponents[j]==row[i]){
                    this.childComponents.splice(j, 1);
                    break;
                }
            }
        }
    }
    this.rowCount--;
    $(this.rows[aIndex][0]).remove();
    $(this.rows[aIndex][1]).remove();
    this.data.splice(aIndex, 1);
    this.rows.splice(aIndex, 1);
};

core.grid.GridPanel.prototype.getRowCount = function(){
    return this.data.length;
};

core.grid.GridPanel.prototype.getRowAt = function(aIndex){
    if(aIndex>=0 && aIndex<this.getRowCount())
        return this.data[aIndex];
};

core.grid.GridPanel.prototype.getRow = function(aID){
    if(!this.allowRowSelect)
        return null;
    for (var i = 0; i < this.data.length; i++) {
        if(this.data[i][this.idIndex]==aID){
            return this.data[i];
        }
    }
    return null;
};

core.grid.GridPanel.prototype.getCell = function(aIndex, aColumn){
    if(aIndex>=this.rowCount){
        aIndex = this.rowCount-1;
    }
    var row = this.data[aIndex];
    if(row && row[aColumn])
        return row[aColumn];
    return null;
};

core.grid.GridPanel.prototype.doFocus = function(){
    this.fire('focus');
	return true;
}

core.grid.GridPanel.prototype.doKeyPress = function(e){
//    core.log('panel keydown', e.which);
    var instance = this;
    if(this.rowCount==0 || !this.allowRowSelect)
        return true;
    if(!this.fire('keypress', e))
        return false;
    if(e.which==40 || e.which==38){
        if(!this.selected){
            this.selectRow(this.data[0][this.idIndex]);
            return false;
        }
        for (var i = 0; i < this.data.length; i++) {
            if(this.data[i][this.idIndex]==this.selected){
                if(e.which==38){
                    if(i>0)
                        this.selectRow(this.data[i-1][this.idIndex]);
                    else{
                        if(this.pager && this.page>1){
                            this.changePage('left', function(){
                                if(instance.rowCount>0)
                                    instance.selectRow(instance.data[instance.rowCount-1][instance.idIndex]);
                            });
                        }
                    }
                }else{
                    if(i<this.data.length-1)
                        this.selectRow(this.data[i+1][this.idIndex]);
                    else{
                        if(this.pager && this.page<this.pages){
                            this.changePage('right', function(){
                                if(instance.rowCount>0)
                                    instance.selectRow(instance.data[0][instance.idIndex]);
                            });
                        }
                    }
                }
                return false;
            }
        }
    }
    return true;
}

core.grid.GridPanel.prototype.addRow = function(aIndex, aData){
    var tr = core.newElement(null, 'tr', 'grid_row_tr');
    var append = false;
    if(aIndex>=this.rowCount){
        aIndex = this.rowCount;
        append = true;
    }
    var row = [];
    var data = $.makeArray(aData);
    for (var i = 0; i < Math.max(this.colCount, data.length); i++) {
        var item = null;
        if(i>=data.length)
            item = '&nbsp;';
        else
            item = data[i];
        row.push(item);
    }
    for (var i = 0; i < this.colCount; i++) {
        if(i>0){
            $(core.newElement(tr, 'td', 'grid_delim')).
                text('').width(core.grid.COLUMN_INTERVAL);
        }
        var td = core.newElement(tr, 'td', 'grid_td');
        if(row[i].instanceID){
            var width = this.columnDef[i];
            if(width>0){
                this.reParent(row[i], td);
                row[i].updateLayout();
                $(row[i].div).addClass('relative');
                row[i].doResize(0, 0, width, row[i].getMinHeight());
                this.childComponents.push(row[i]);
//                core.log('Add to components', row[i].instanceID, this.childComponents.length);
            }else{
                
            }

        }else
            $(td).html(row[i]);
        if(this.allowRowSelect){
            var instance = this;
            $(td).attr('rowid', row[this.idIndex]).
                click(function(e){
                    instance.fire('focus');
                    instance.selectRow($(this).attr('rowid'))
                    instance.fire('click', {}, instance.selected, instance.selectedRow);
                    return true;
                }).dblclick(function(e){
                    instance.fire('dblclick', e, instance.selected, instance.selectedRow);
                    e.preventDefault();
                    return false;
                });
        }
    }
    var tbody = $(this.grid).children().get(0);
    var r = [];
    r[0] = tr;
    r[1] = this.makeDelimRow();
    if(append){
        this.data.push(row);
        $(r[0]).insertBefore($(tbody).children().get(this.rowCount*2+1));
        $(r[1]).insertBefore($(tbody).children().get(this.rowCount*2+1));
        this.rows.push(r);
    }else{
        this.data.splice(aIndex, 0, row);
        this.rows.splice(aIndex, 0, r);
        $(r[0]).insertBefore($(tbody).children().get(aIndex*2+1));
        $(r[1]).insertBefore($(tbody).children().get(aIndex*2+1));
    }
    this.rowCount++;
};

core.grid.GridPanel.prototype.selectRow = function(aID, aAutomatic){
    for (var i = 0; i < this.data.length; i++) {
        var row = this.data[i];
        if(row[this.idIndex]==aID){
            if(this.selected==aID)
                return false;
            if(this.selected){
                this.fire('unselect', {}, this.selected, this.selectedRow);
            }
            this.selected = aID;
            this.selectedRow = row;
            this.fire('select', {
                automatic: aAutomatic
            }, this.selected, this.selectedRow);
            //#ifdef DESKTOP
            this.moveFrame(aID);
            //#endif
            return true;
        }
    }
    this.selected = null;
    this.selectedRow = null;
    return false;
}

core.grid.GridPanel.prototype.setWidth = function(aWidth){
	this.width = aWidth;
    
    var availWidth = aWidth - this.fixedWidth-core.grid.SCROLLBAR_OFFSET;
    if(availWidth<0)
        availWidth = 0;
    var widths = [];
    for (var i = 0; i < this.colCount; i++) {
        if(this.columnDef[i]>1)
            widths.push(this.columnDef[i]);
        else{
            widths.push(Math.floor(availWidth*this.columnDef[i]/this.floatWidth));
        }
    };
    var hh = 0;
    if(this.headerVisible){
        for (var i = 0; i < this.colCount; i++) {
            var td = $(this.headerTR).children().get(i*2);
            $(td).width(widths[i]);
        }
        $(this.header).width(aWidth-core.grid.SCROLLBAR_OFFSET);
        hh = $(this.header).height() || 50;
//        core.log('Header h', $(this.header).height(), hh);
    }
//    $(this.gridDiv).width(aWidth).height(aHeight-hh);
    for (var i = 0; i < this.colCount; i++) {
        var td = $(this.firstRow).children().get(i*2);
        $(td).width(widths[i]);
    }
    $(this.grid).width(aWidth-core.grid.SCROLLBAR_OFFSET);
    this.headerHeight = hh;
//    if(this.pager){
//        this.pagerBox.refreshDimensions(aWidth, BUTTON_HEIGHT);
//        this.headerHeight += this.pagerBox.height;
//    }
//    core.log('grid header height:', this.headerHeight, $(this.grid).height());
//#ifdef MOBILE
    this.minHeight = hh+$(this.grid).height();
//#endif
};

core.grid.GridPanel.prototype.makeResize = function(aX, aY, aWidth, aHeight){
//    if(this.pager){
//        this.pagerBox.resize(0, 0, aWidth, this.pagerBox.height);
//    }
    $(this.gridDiv).width(aWidth).height(aHeight-this.headerHeight);
    var count = 0;
    for (var i = 0; i < this.childComponents.length; i++) {
        if(this.childComponents[i].refresh())
            count++;
    }
//    core.log('table resize: '+this.childComponents.length+", "+count);
//#ifdef DESKTOP
    if(this.selected){
        this.moveFrame(this.selected);
    }
//#endif
};

core.grid.GridPanel.prototype.gridItemAdded = function(aData){
    var arr = this.get('add_item', aData);
    this.addRow(aData.index, arr);
    this.updatePager(aData.state);
    this.bodyChanged();
};

core.grid.GridPanel.prototype.gridItemRemoved = function(aData){
    this.removeRow(aData.index);
    this.updatePager(aData.state);
    this.bodyChanged();
};

core.grid.GridPanel.prototype.gridItemSelected = function(aData){
    this.selectRow(aData.id);
};

core.grid.GridPanel.prototype.setGridState = function(aData){
    this.updatePager(aData);
}

core.grid.GridPanel.prototype.loadGrid = function(aData){
    var items = $.makeArray(aData.items);
    this.clear();
    for (var i = 0; i < items.length; i++) {
        var arr = this.get('add_item', items[i]);
        this.addRow(i, arr);
    }
    this.selectRow(aData.selected, true);
//#ifdef DESKTOP
    if(!this.selected){
        $(this.gridDiv).scrollTop(0);
    }
//#endif
    this.updatePager(aData.state);
    this.bodyChanged();
};
